//
//  LittleBallPlayViewController.m
//  LittleBall
//
//  Created by mac on 11-12-23.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "LittleBallPlayViewController.h"

@implementation LittleBallPlayViewController

@synthesize m_gameManagement;
@synthesize gameScore;

@synthesize coreEmitter;
@synthesize fireEmitter;
@synthesize smokeEmitter;
//@synthesize fireEmitter_down;
//@synthesize smokeEmitter_down;
//@synthesize fireEmitter_left;
//@synthesize smokeEmitter_left;
//@synthesize fireEmitter_right;
//@synthesize smokeEmitter_right;

- (id)init
{
    self = [super init];
    if (self) {

    }
    
    return self;
}

//-------------------------------------------------------------------------------------
- (IBAction)onButton_gamePause:(id)sender
{
    if (gamePause != YES)
    {
        gamePause = YES;
        NSString *pauseImgPath = [[NSBundle mainBundle] pathForResource:@"pause" ofType:@"png"];
        CGPoint centerPoint = CGPointMake(384.0f, 400.0f);
        UIImage *pauseImg = [[UIImage alloc] initWithContentsOfFile:pauseImgPath];
        m_pauseView = [[UIImageView alloc] initWithImage:pauseImg];
        m_pauseView.center = centerPoint;
        m_pauseView.alpha = 0.7;
        [self.view addSubview:m_pauseView]; 
        
        [m_gamePause setTitle:@"继续游戏" forState: UIControlStateNormal];
    }
    else
    {
        gamePause = NO;
        
        [m_pauseView removeFromSuperview];  
        
        [m_gamePause setTitle:@"暂停游戏" forState: UIControlStateNormal];
    }
}

- (IBAction)onButton_goBack:(id)sender
{
    [m_propertyViewController savePropertiesData];
    
    [self.view removeFromSuperview];
    [self resetGame];        // 如果需要从主界面resume返回游戏，则取消此处；但不建议
}
//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
- (void)initializePlayView
{
    m_pathFinder = [[LBPathFinder alloc] init];
    m_pathFinder2 = [[LBPathFinder alloc] init];
    m_ballArray = [[NSMutableArray alloc] initWithCapacity:BALL_NUM_MAX];
    
//--------------------  绘制单元格
    NSString *unitImgPath = [[NSBundle mainBundle] pathForResource:@"play_background_unit" ofType:@"png"];
    CGPoint centerPoint = CGPointMake(COORDINATE_START_X+BALL_WIDTH/2, COORDINATE_START_Y+BALL_HEIGHT/2);
    UIImage *playUnitImg = [[UIImage alloc] initWithContentsOfFile:unitImgPath];
    
    for(int i = 0; i < MAX_ROW; i++)
    {
        for( int j=0; j < MAX_COLUMN; j++ )
        {
            UIImageView *backgroundUnit = [[UIImageView alloc] initWithImage:playUnitImg];
            backgroundUnit.center = centerPoint;
            [self.view addSubview:backgroundUnit];         
            centerPoint.x += BALL_WIDTH;
        }
        centerPoint.y += BALL_HEIGHT;
        centerPoint.x = COORDINATE_START_X+BALL_WIDTH/2;
    }

//--------------------  小球视图
    NSString *ballImgPath = [[NSBundle mainBundle] pathForResource:@"ball_red" ofType:@"png"];
    m_imageArrary[BALL_COLOR_RED] = [[UIImage alloc] initWithContentsOfFile:ballImgPath];
    
    ballImgPath = [[NSBundle mainBundle] pathForResource:@"ball_blue" ofType:@"png"];
    m_imageArrary[BALL_COLOR_BLUE] = [[UIImage alloc] initWithContentsOfFile:ballImgPath];
    
    ballImgPath = [[NSBundle mainBundle] pathForResource:@"ball_green" ofType:@"png"];
    m_imageArrary[BALL_COLOR_GREEN] = [[UIImage alloc] initWithContentsOfFile:ballImgPath];
    
    ballImgPath = [[NSBundle mainBundle] pathForResource:@"ball_orange" ofType:@"png"];
    m_imageArrary[BALL_COLOR_ORANGE] = [[UIImage alloc] initWithContentsOfFile:ballImgPath];
    
//-------------------- 加载道具容器
    m_propertyViewController = [[LittleBallPropertyViewController alloc] initWithNibName:@"LittleBallPropertyViewController" bundle:nil];
    m_propertyViewController.m_playViewController = self;
    [self.view addSubview:m_propertyViewController.view];
    
    m_bPropertyPlaying = FALSE;

//--------------------  当前视图音乐音效，需全部加载完毕，否则游戏可能会卡。menuView和playView为两套背景音乐。
//    未来需要激活，播放playView的背景音乐和音效
//    [m_gameManagementForPlayView loadBackgroundMusicwithName:@"" Type:@""];
//    [m_gameManagementForPlayView playBackgroundMusic];
    
//    [m_gameManagementForPlayView loadSoundEffectwithName:@"" fileType:@"" goal:EFFECT_SOUND_BUTTON];
//    [m_gameManagementForPlayView loadSoundEffectwithName:@"clearball" fileType:@"WAV" goal:EFFECT_SOUND_CLEARBALL];
    [m_gameManagement loadSoundEffectwithName:@"clearball" fileType:@"WAV" goal:EFFECT_SOUND_CLEARBALL];
      
//    [m_gameManagementForPlayView loadSoundEffectwithName:@"" fileType:@"" goal:EFFECT_SOUND_WIN];
//    [m_gameManagementForPlayView loadSoundEffectwithName:@"" fileType:@"" goal:EFFECT_SOUND_LOSE];
//    [m_gameManagementForPlayView loadSoundEffectwithName:@"" fileType:@"" goal:EFFECT_SOUND_DEFAULT];  
    
//-------------------- 一些初始化动作
    nextBallColorArray = nil;
    nextBallLittlePicArray = nil;
}

- (void)setGameMode:(GAME_MODE)input
{
    gameMode = input;
}

- (void)setGameConfiguration
{
    timeSeconds = 0;
    gameScore   = 0;
    m_prevSelectedBall = nil;
    int gameDifficulty = [m_gameManagement getGameDifficluty];
    
    if (gameMode == TRADITONAL_MODE)
    {
        if (gameDifficulty == EASY)
        {
            randomBallGenNum = RANDOM_BALL_GEN_NUM_INIT_TRADITIONAL_EASY;
            initNumberForTraditional = INIT_NUMBER_TRADITIONAL_EASY;
        }
        else if (gameDifficulty == MEDIUM)
        {
            randomBallGenNum = RANDOM_BALL_GEN_NUM_INIT_TRADITIONAL_MEDIUM;
            initNumberForTraditional = INIT_NUMBER_TRADITIONAL_MEDIUM;
        }
        else
        {
            randomBallGenNum = RANDOM_BALL_GEN_NUM_INIT_TRADITIONAL_HARD;
            initNumberForTraditional = INIT_NUMBER_TRADITIONAL_HARD;
        }
        
         m_newPositions = [m_pathFinder getPositionsWithNum:initNumberForTraditional withState:POSITION_EMPTY];
        [self generateNewBalls];

    }
    else
    {
        if (gameDifficulty == EASY)
        {
            randomBallGenNum = RANDOM_BALL_GEN_NUM_INIT_TRADITIONAL_EASY;
        }
        else if (gameDifficulty == MEDIUM)
        {
            randomBallGenNum = RANDOM_BALL_GEN_NUM_INIT_TRADITIONAL_MEDIUM;
        }
        else
        {
            randomBallGenNum = RANDOM_BALL_GEN_NUM_INIT_TRADITIONAL_HARD;
        }
    }
}
//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------    
- (void)startGame
{
    m_timer = [NSTimer scheduledTimerWithTimeInterval:SYS_TIMER_INTERVAL target:self selector:@selector(onTimer) userInfo:nil repeats:TRUE];
}


- (void)onTimer
{
    if (gamePause != YES)
    {
        timeSeconds++;
    }
    
    //[m_timeLabel setText:[NSString stringWithFormat:@"%04d",timeSeconds%SECONDS_MOD_BASE]];
    int timeSecondsTmp = timeSeconds;
    
    int hour = timeSecondsTmp/3600;
    timeSecondsTmp -= hour*3600;
    int minute = timeSecondsTmp/60;
    timeSecondsTmp -= minute*60;
    int second = timeSecondsTmp;
    
    [m_timeLabel setText:[NSString stringWithFormat:@"%02d:%02d:%02d",hour,minute,second]];
    
    if (gamePause != YES)
    {
        if (gameMode == SURVIVAL_MODE)
        {
            if ( timeSeconds % BAL_GEN_INTERVAL_EASY == 0 || timeSeconds == 1 ) 
            {
                [self generateNewBalls];
            }
            
            /*
             游戏中的其它机制暂不支持此升级，需要待定
            if( timeSeconds % INCREASE_BALL_GEN_NUM_INTERVER == 0 && randomBallGenNum < MAX_BALL_GEN_NUM )
            {
                randomBallGenNum++;
            }
            */
        }  
    }
}

//-------------------------------------------------------------------------------------

-(void)clearPreShowInfo
{
    // 清空数组
    [nextBallColorArray removeAllObjects];
    
    while ([nextBallLittlePicArray count] > 0) 
    {
        UIImageView *nextBallImageToBeCleared = [nextBallLittlePicArray objectAtIndex:0];
        
        [nextBallImageToBeCleared removeFromSuperview];
        
        [nextBallLittlePicArray removeObject:nextBallImageToBeCleared];
    }
}

-(void)generateNewBalls
{
    //static NSMutableArray *nextBallColorArray;
    //static NSMutableArray *nextBallLittlePicArray;

    m_newPositions = [m_pathFinder getPositionsWithNum:randomBallGenNum withState:POSITION_EMPTY];
    
    if( [m_newPositions count] == 0 )
    {
        [self gameOver];
    }
    else
    {
        for (int i = 0; i < [m_newPositions count]; i++) 
        {
            NSLog(@"array length: %d, objectAtIndex:%d, File:%s, Line:%d",[m_newPositions count],i,__FILE__,__LINE__);
            LBPosition *position = [m_newPositions objectAtIndex:i];
            
            if ( nil == nextBallColorArray ) 
            {
                [self createBallWithColor:arc4random()%BALL_COLOR_NUM atRow:position.m_row atColumn:position.m_column];
            }
            else
            {
                NSLog(@"array length: %d, objectAtIndex:%d, File:%s, Line:%d",[nextBallColorArray count],i,__FILE__,__LINE__);
                [self createBallWithColor:[[nextBallColorArray objectAtIndex:i] intValue] atRow:position.m_row atColumn:position.m_column];
            }            
        }
        
        if( MAX_COLUMN*MAX_ROW == [m_ballArray count] )
        {
            [self gameOver];
        }
    }
    
    // 产生随机预置数    
    if( nil == nextBallColorArray )
    {
        nextBallColorArray = [[NSMutableArray alloc] initWithCapacity:randomBallGenNum];
    }
    // 根据随机预置数生成提示小图标
    if( nil == nextBallLittlePicArray )
    {
        nextBallLittlePicArray = [[NSMutableArray alloc] initWithCapacity:randomBallGenNum];
    }
    
    // 清空数组
    [self clearPreShowInfo];
    
    CGFloat y = 7;
    CGFloat x = 36;
    CGFloat width = 26;
    CGFloat height = width;
    CGFloat distance = 34;
    
    for (int i=0; i < randomBallGenNum; i++) 
    {
        NSNumber *nextBallColorID = [[NSNumber alloc] initWithInt:arc4random()%BALL_COLOR_NUM];
        [nextBallColorArray addObject:nextBallColorID];
        
        UIImage *image = m_imageArrary[[nextBallColorID intValue]];
        UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
        imageView.frame = CGRectMake(x+distance*i, y, width, height);
        imageView.center = CGPointMake(x+distance*i+width/2, y+height/2);
        
        [self.view addSubview:imageView];
        [nextBallLittlePicArray addObject:imageView];        
    }    
}

- (enum LBErrorCodeType)createBallWithColor:(BALL_COLOR)color atRow:(int)row atColumn:(int)column
{    
    // 检查待创建的位置是否合法
    if( FALSE == [self checkPositionEmptyAtRow:row atColumn:column] )
    {
        return LB_BALL_EXIST;
    }
    
    // 设定小球图片
    UIImage *image = m_imageArrary[color];
    
    // 创建小球
    LBBall *ball = [[LBBall alloc] initWithImage:image atRow:row atColumn:column withColor:color];
    
    if( ball )
    {    
        // 将球加入管理结构并设置地图数据
        if( m_ballArray )
        {
            [m_ballArray addObject:ball];
            
            LBPosition *position = [[LBPosition alloc] initWithRow:ball.m_row column:ball.m_column];
            [m_pathFinder setPositionStateToMapWithType:MAP_SOURCE atPosition:position toState:POSITION_BALL];
        }
        else
        {
            NSLog(@"m_imageArrary is nil!");
            return LB_ERROR;
        }
        
        // 显示小球
        [self.view addSubview:ball.m_imageView];
        
        // 产生及判断消除状态
        [self clearBallsWithBall:ball];
        
        return LB_SUCCESS;
    }
    return LB_ERROR;
}

- (BOOL)checkPositionEmptyAtRow:(int)row atColumn:(int)column
{
    LBBall *ball = [self getBallByRow:row column:column];
    
    if (ball) 
    {
        NSLog(@"at row: %d, column: %d, there is already a ball!", row, column);
        return FALSE;
    }
    
    return TRUE;
}

- (LBBall *)getBallByRow:(int)row column:(int)column
{
    NSEnumerator* enumerator = [m_ballArray objectEnumerator];
    
    id anObject = [enumerator nextObject];
    
    while (anObject != nil)
    {
        if( [anObject ifTheBallIsAtRow:row atColumn:column] )
        {
            return anObject;
        }
        
        anObject = [enumerator nextObject];
    }
    
    return nil;
}
//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
- (BOOL)clearBallsWithBall:(LBBall *)ball
{

    int ext = 0; // 加分系数
    int count;
    LBBall *ballTemp = nil;
    BOOL bBallNeedTobeCleared = FALSE;
    
    NSMutableArray     *horBalls = [[NSMutableArray alloc] init]; // 水平方向上，相连同色小球的集合
    NSMutableArray     *verBalls = [[NSMutableArray alloc] init]; // 垂直方向上，相连同色小球的集合
    NSMutableArray     *diaRBalls = [[NSMutableArray alloc] init]; // 左上至右下对角线
    NSMutableArray     *diaLBalls = [[NSMutableArray alloc] init]; // 右上至坐下对角线
    
    //--------------
    // up    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row-count column:ball.m_column];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [verBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row-count column:ball.m_column];
            continue;
        }
        
        break;
    }
    
    // down    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row+count column:ball.m_column];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [verBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row+count column:ball.m_column];
            continue;
        }
        
        break;
    }
    
    // left    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row column:ball.m_column-count];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [horBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row column:ball.m_column-count];
            continue;
        }
        
        break;
    }
    
    // right    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row column:ball.m_column+count];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [horBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row column:ball.m_column+count];
            continue;
        }
        
        break;
    }
    
    //-------------------
    
    // up    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row-count column:ball.m_column-count];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [diaRBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row-count column:ball.m_column-count];
            continue;
        }
        
        break;
    }
    
    // down    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row+count column:ball.m_column+count];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [diaRBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row+count column:ball.m_column+count];
            continue;
        }
        
        break;
    }
    
    // left    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row-count column:ball.m_column+count];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [diaLBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row-count column:ball.m_column+count];
            continue;
        }
        
        break;
    }
    
    // right    
    count = 1;
    ballTemp = [self getBallByRow:ball.m_row+count column:ball.m_column-count];
    while (ballTemp)
    {
        if( ballTemp.m_color == ball.m_color )
        {
            [diaLBalls addObject:ballTemp];
            count++;
            ballTemp = [self getBallByRow:ball.m_row+count column:ball.m_column-count];
            continue;
        }
        
        break;
    }
    
    //-------------------
    
    int ballNumTobeCleared = [verBalls count];
    if( [verBalls count] >= BALL_NUM_CLEAR-1  )
    {
        // 纵向消除
        bBallNeedTobeCleared = TRUE;
        
        while ([verBalls count] > 0) 
        {
            LBBall *ballToBeCleared = [verBalls objectAtIndex:0];
            
            [self destroyBall:ballToBeCleared];
            
            [verBalls removeObject:ballToBeCleared];
        }
        
        ext++;
        
    }
    
    ballNumTobeCleared += [horBalls count];
    if( [horBalls count] >= BALL_NUM_CLEAR-1 )
    {
        // 横向消除
        bBallNeedTobeCleared = TRUE;
        
        while ([horBalls count] > 0) 
        {
            LBBall *ballToBeCleared = [horBalls objectAtIndex:0];
            
            [self destroyBall:ballToBeCleared];
            
            [horBalls removeObject:ballToBeCleared];
        }
        
        ext++;
        
    }
    
    ballNumTobeCleared += [diaRBalls count];
    if( [diaRBalls count] >= BALL_NUM_CLEAR-1  )
    {
        // 左上至右下消除
        bBallNeedTobeCleared = TRUE;
        
        while ([diaRBalls count] > 0) 
        {
            LBBall *ballToBeCleared = [diaRBalls objectAtIndex:0];
            
            [self destroyBall:ballToBeCleared];
            
            [diaRBalls removeObject:ballToBeCleared];
        }
        
        ext++;
        
    }
    
    ballNumTobeCleared += [diaLBalls count];
    if( [diaLBalls count] >= BALL_NUM_CLEAR-1 )
    {
        // 右上至左下消除
        bBallNeedTobeCleared = TRUE;
        
        while ([diaLBalls count] > 0) 
        {
            LBBall *ballToBeCleared = [diaLBalls objectAtIndex:0];
            
            [self destroyBall:ballToBeCleared];
            
            [diaLBalls removeObject:ballToBeCleared];
        }
        
        ext++;
        
    }
    
    if( bBallNeedTobeCleared )
    {
        [m_gameManagement playSoundEffectWithType:EFFECT_SOUND_CLEARBALL];
        
        int currentScore = ((ballNumTobeCleared+1)*(ext));
        gameScore += currentScore;
        //[m_scoreLabel setText:[NSString stringWithFormat:@"%d",gameScore]];
        [self refreshScoreDisplay];
        
        [self showCurrentScoreWithScore:currentScore withLabel:m_currentScoreLabel withCenterPoint:ball.m_imageView.center];
        [self destroyBall:ball];
        
        return YES;
    }
    else
    {
        return NO;
    }
}

-(void)destroyBall:(LBBall *)ball
{
    LBPosition  *position = [[LBPosition alloc] initWithRow:ball.m_row column:ball.m_column];
    
    // 清除球在地图上的对应标记
    [m_pathFinder setPositionStateToMapWithType:MAP_SOURCE atPosition:position toState:POSITION_EMPTY];
    
    // 将球从父view中移出
    [ball.m_imageView removeFromSuperview];
    
    // 从array中移除小球
    [m_ballArray removeObject:ball];
}

- (void)showCurrentScoreWithScore:(int)score withLabel:(UILabel *)label withCenterPoint:(CGPoint)centerPoint
{
    label.center = centerPoint;
    
    m_showCurrentScoreAnimationDelegate = [[LBShowCurrentScoreAnimationDelegate alloc] initWithScore:score withLabel:label owner:self];
}

//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (gamePause != YES && m_bPropertyPlaying != TRUE)
    {
        UITouch *touch = [[event allTouches] anyObject];
        
        CGPoint    touchPoint = [touch locationInView:self.view];
        
        // 如果有道具选中，则进行道具相关操作处理
        if ([m_propertyViewController isPropertySelected]) 
        {
            int rowTmp;
            int columnTmp;
            
            if ([LBPathFinder tranllateTouchPointToPositionFromPoint:touchPoint toRow:&rowTmp toColumn:&columnTmp]) 
            {
                m_bPropertyPlaying = TRUE;
                
                // 如果点中格子，则依据不同的道具类型进行不同的施放处理
                switch ([m_propertyViewController getPropertyType]) 
                {
                    case LB_PROPERTY_BOMB:
                        {
                            LBBomb *bomb = [[LBBomb alloc]init];
                            bomb.m_column = columnTmp;
                            bomb.m_row = rowTmp;
                            bomb.m_damage = [m_propertyViewController getPropertyLevel];
                            
                            [self bomb:bomb];
                        
                        }
                        break;
                        
                    case LB_PROPERTY_COLORBALL:
                        {
                            // 暂时还原
                            
                            // 结束道具选取状态
                            [m_propertyViewController resetPropertyState];
                            m_bPropertyPlaying = FALSE;
                        }
                        break;
                        
                    default:
                        {
                            m_bPropertyPlaying = FALSE;
                        }
                        break;
                }
                
                // 取消道具选中状态
                //[m_propertyViewController resetPropertyState];
            }
            return;
        }
        
        // 没有道具选中，继续小球移动或点选操作处理
        LBBall     *ball = [self getBallByTouchPoint:touchPoint];
        
        if (ball)  //当前有新选中的Ball
        {
            if( m_prevSelectedBall )
            {
                // 之前有已选中的Ball，先将其动画停止
                [self unSelectABallAtRow:m_prevSelectedBall.m_row atColumn:m_prevSelectedBall.m_column];
                
                m_prevSelectedBall = nil;
            }
            
            // 开启当前Ball的动画
            [self selectABallAtRow:ball.m_row atColumn:ball.m_column];
            m_prevSelectedBall = ball;
        }
        else
        {
            int rowTmp;
            int columnTmp;
            
            if ([LBPathFinder tranllateTouchPointToPositionFromPoint:touchPoint toRow:&rowTmp toColumn:&columnTmp]) 
            {
                
                if(m_prevSelectedBall)
                {
                    // 之前有已选中的Ball，需要移动到空格上
                    LBPosition *startPosition=[[LBPosition alloc] initWithRow:m_prevSelectedBall.m_row column:m_prevSelectedBall.m_column];
                    LBPosition *endPosition=[[LBPosition alloc] initWithRow:rowTmp column:columnTmp];              
                    
                    if (simultaneityFlag == YES)  // 第二个小球
                    {
                        if ([m_pathFinder2 findPathFromStartPosition:startPosition toEndPosition:endPosition]) 
                        {
                            // 能够获取到移动路径，停止被选中动画，开启移动动画
                            
                            if ( !((endPosition.m_row == endPosition1.m_row) && (endPosition.m_column == endPosition1.m_column)) )
                            {
                                [self unSelectABallAtRow:m_prevSelectedBall.m_row atColumn:m_prevSelectedBall.m_column];
                                
                                [self moveBall:m_prevSelectedBall byPath:m_pathFinder2.m_parthPoints];                            
                                
                                // 设置移动前的位置为空，移动后为被Ball占用, 并且刷新Ball本身的属性
                                [m_pathFinder2 setPositionStateToMapWithType:MAP_SOURCE atPosition:startPosition toState:POSITION_EMPTY];                    
                                [m_pathFinder2 setPositionStateToMapWithType:MAP_SOURCE atPosition:endPosition toState:POSITION_BALL];
                                
                                m_prevSelectedBall.m_column = endPosition.m_column;
                                m_prevSelectedBall.m_row = endPosition.m_row;
                                m_prevSelectedBall.m_bSelected = FALSE;
                                
                                // 设置没有Ball被选中
                                m_prevSelectedBall = nil;
                            }
                            
                        }   
                        
                    }
                    
                    if (simultaneityFlag == NO)   // 第一个小球
                    {
                        
                        startPosition1=[[LBPosition alloc] initWithRow:m_prevSelectedBall.m_row column:m_prevSelectedBall.m_column];
                        endPosition1=[[LBPosition alloc] initWithRow:rowTmp column:columnTmp];
                        
                        if ([m_pathFinder findPathFromStartPosition:startPosition toEndPosition:endPosition]) 
                        {
                            // 能够获取到移动路径，停止被选中动画，开启移动动画
                            [self unSelectABallAtRow:m_prevSelectedBall.m_row atColumn:m_prevSelectedBall.m_column];
                            
                            simultaneityFlag = YES;
                            
                            [self moveBall:m_prevSelectedBall byPath:m_pathFinder.m_parthPoints];
                            
                            
                            // 设置移动前的位置为空，移动后为被Ball占用, 并且刷新Ball本身的属性
                            [m_pathFinder setPositionStateToMapWithType:MAP_SOURCE atPosition:startPosition toState:POSITION_EMPTY];                    
                            [m_pathFinder setPositionStateToMapWithType:MAP_SOURCE atPosition:endPosition toState:POSITION_BALL];
                            
                            m_prevSelectedBall.m_column = endPosition.m_column;
                            m_prevSelectedBall.m_row = endPosition.m_row;
                            m_prevSelectedBall.m_bSelected = FALSE;
                            
                            // 设置没有Ball被选中
                            m_prevSelectedBall = nil;
                        } 
                    }
                }
            }        
        }
    }
}

- (LBBall *)getBallByTouchPoint:(CGPoint)touchPoint
{
    NSEnumerator* enumerator = [m_ballArray objectEnumerator];
    
    id anObject = [enumerator nextObject];
    
    while (anObject != nil)
    {
        if( [anObject ifTheBallCoverThePoint:touchPoint] )
        {
            return anObject;
        }
        
        anObject = [enumerator nextObject];
    }
    
    return nil;    
}

- (void)selectABallAtRow:(int)row atColumn:(int)column
{
    LBBall *ball = [self getBallByRow:row column:column];
    
    // Use UIView's built-in animation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationRepeatCount:9999];
    
    m_ballSelectedAnimationDelegate = [[LBBallSelectedAnimationDelegate alloc] initWithBall:ball owner:self];
    
    [UIView commitAnimations];
}



- (void)unSelectBall
{
    if( m_prevSelectedBall )
    {
        [self unSelectABallAtRow:m_prevSelectedBall.m_column atColumn:m_prevSelectedBall.m_row];
    }
    
    m_prevSelectedBall = nil;    
}

- (void)unSelectABallAtRow:(int)row atColumn:(int)column
{
    //LBBall *ball = [self getBallByRow:row column:column];
    
    // Use UIView's built-in animation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationRepeatCount:1];
    
    m_ballSelectedAnimationDelegate.m_bContinueAnimation = FALSE;
    
    [UIView commitAnimations];
}

- (void)moveBall:(LBBall *)ball byPath:(NSMutableArray *)path
{
    if (m_ballMoveAnimationDelegate == nil)
    {
        m_ballMoveAnimationDelegate = [[LBMoveAnimationDelegate alloc] initWithPath:path ball:ball owner:self];
    }
    else
    {
        m_ballMoveAnimationDelegate2 = [[LBMoveAnimationDelegate alloc] initWithPath:path ball:ball owner:self];
    }
}

- (void)setFlag:(BOOL)input
{
    simultaneityFlag = input;
}

- (GAME_MODE)getGameMode
{
    return gameMode;
}


- (int)getGameDifficluty
{
    return [m_gameManagement getGameDifficluty];
}


//-------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------
- (void)resetGame
{
    gameScore = 0;
    timeSeconds = 0;
    
    /*
     NSMutableArray        *nextBallColorArray;
     NSMutableArray        *nextBallLittlePicArray;
     */
    
    [self clearPreShowInfo];
    nextBallColorArray = nil;
    nextBallLittlePicArray = nil;
    
    
    //[m_timeLabel setText:[NSString stringWithFormat:@"%04d",0%SECONDS_MOD_BASE]];
    [m_timeLabel setText:[NSString stringWithFormat:@"00:00:00"]];
    //[m_scoreLabel setText:[NSString stringWithFormat:@"0"]];
    [self refreshScoreDisplay];
    [m_timer invalidate];

    while ([m_ballArray count] > 0) 
    {
        LBBall *ballToBeCleared = [m_ballArray objectAtIndex:0];
        
        [self destroyBall:ballToBeCleared];
        
        [m_ballArray removeObject:ballToBeCleared];
    }
    
    [self setGameConfiguration];
    
    // ... TBD
}

- (void)gameOver
{
    [m_timer invalidate];
    
    m_loseAlert = [[UIAlertView alloc] initWithTitle:nil message:@DEAD_PROMPT delegate:self cancelButtonTitle:@DEAD_CANCEL_TEXT otherButtonTitles:nil, nil];
    
    [m_loseAlert show];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    switch (interfaceOrientation) 
    {
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
            return true;
            
        default:
            break;
    }
    
    return false;
}

//- (void)alertViewCancel:(UIAlertView *)alertView
//{
//    if( m_loseAlert == alertView )
//    {
//        [self resetGame];
//        [self startGame];
//    }
//}
//
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if( m_loseAlert == alertView && 0 == buttonIndex )
    {
        [self resetGame];
        [self startGame];
    }
}


// 道具施放
- (BOOL)bomb:(LBBomb *)bomb
{
    
    int ext = 0; // 加分系数
    int damagRowTotal = 0;
    int damagColumnTotal = 0;
    LBBall *ballTemp = nil;
    BOOL bBallNeedTobeCleared = FALSE;
    
    NSMutableArray *ballsToClear = [[NSMutableArray alloc] init];
    
    switch (bomb.m_damage) 
    {
        case 1:
        default:
            {
                damagRowTotal = 1;
                damagColumnTotal = 1;
            }
            break;
            
        case 2:
            {
                damagRowTotal = 3;
                damagColumnTotal = 3;
            }
            break;
            
        case 3:
            {
                damagRowTotal = 5;
                damagColumnTotal = 5;
            }
            break;
    }
    
    int rowCount = 0;
    int columnCount = 0;
    
    for ( ; rowCount < damagRowTotal; rowCount++) 
    {
        for ( columnCount = 0; columnCount < damagColumnTotal; columnCount++) 
        {
            ballTemp = [self getBallByRow:bomb.m_row+(rowCount-(damagRowTotal-1)/2) column:bomb.m_column+(columnCount-(damagColumnTotal-1)/2)];
            
            if( ballTemp )
            {
                [ballsToClear addObject:ballTemp];
            }
        }
    }
    

    
    int ballNumTobeCleared = [ballsToClear count];
    if( ballNumTobeCleared > 0  )
    {
        bBallNeedTobeCleared = TRUE;
        
        while ([ballsToClear count] > 0) 
        {
            LBBall *ballToBeCleared = [ballsToClear objectAtIndex:0];
            
            [self destroyBall:ballToBeCleared];
            
            [ballsToClear removeObject:ballToBeCleared];
        }
        
        ext++;
    }

    {
        // 释放效果动画
        [self releaseBombEmittersWithBomb:bomb];
        
        // 得分动画
        [m_gameManagement playSoundEffectWithType:EFFECT_SOUND_CLEARBALL];
        
        int currentScore = ((ballNumTobeCleared+1)*(ext));
        gameScore += currentScore;
        //[m_scoreLabel setText:[NSString stringWithFormat:@"%d",gameScore]];
        [self refreshScoreDisplay];
        
        [self showCurrentScoreWithScore:currentScore withLabel:m_currentScoreLabel withCenterPoint:bomb.m_imageView.center];
        //[self destroyBall:ball];
        
        return YES;
    }
}

- (void)releaseBombEmittersWithBomb:(LBBomb *)bomb
{
    //CGRect viewBounds = self.view.layer.bounds;
	CGPoint bombPoint = [LBPathFinder translatePositionToCenterPointFromRow:bomb.m_row column:bomb.m_column];
    
    
    // Begin // Fire /////////////////////////////////////////////////////////////
	// Create the emitter layers
	self.coreEmitter = [CAEmitterLayer layer];
	self.coreEmitter.emitterPosition = bombPoint;
    self.coreEmitter.emitterMode	= kCAEmitterLayerSurface;
	self.coreEmitter.emitterShape	= kCAEmitterLayerCircle; // 粒子
	self.coreEmitter.renderMode		= kCAEmitterLayerAdditive; // with additive rendering the dense cell distribution will create "hot" areas
    
	// Create the fire emitter cell
	CAEmitterCell* core = [CAEmitterCell emitterCell];
	[core setName:@"core"];
    
	core.birthRate			= 800;
	core.emissionLongitude  = M_PI*2;
	core.velocity			= 500;
	core.velocityRange		= 0;
	core.emissionRange		= M_PI*2; //1.1;
	core.yAcceleration		= 0;
    core.zAcceleration		= 800;
	core.scaleSpeed		    = 1;
	core.lifetime			= 0.2;
	core.lifetimeRange		= 0.2;
    core.spin               = 0.5;
    core.spinRange			= 6;
    core.alphaSpeed		    = -0.40;
    core.color = [[UIColor colorWithRed:0.8 green:0.6 blue:0.4 alpha:0.2] CGColor];
	core.contents = (id) [[UIImage imageNamed:@"bomb_unit"] CGImage];
    // End // Fire ////////////////////////////////////////////////////////////////
    
    // Begin // Fire /////////////////////////////////////////////////////////////
	// Create the emitter layers
	self.fireEmitter = [CAEmitterLayer layer];
	self.fireEmitter.emitterPosition = bombPoint;
    self.fireEmitter.emitterMode	= kCAEmitterLayerOutline;
	self.fireEmitter.emitterShape	= kCAEmitterLayerCircle; // 粒子
	self.fireEmitter.renderMode		= kCAEmitterLayerAdditive; // with additive rendering the dense cell distribution will create "hot" areas

	// Create the fire emitter cell
	CAEmitterCell* fire = [CAEmitterCell emitterCell];
	[fire setName:@"fire"];
    
	fire.birthRate			= 800;
	fire.emissionLongitude  = M_PI*2;
	fire.velocity			= 500;
	fire.velocityRange		= 500;
	fire.emissionRange		= M_PI*2; //1.1;
	fire.yAcceleration		= 0;
    fire.zAcceleration		= 800;
	fire.scaleSpeed		    = 1;
	fire.lifetime			= 0.2;
	fire.lifetimeRange		= 0.2;
    fire.spin               = 0.5;
    fire.spinRange			= 6;
    fire.alphaSpeed		    = -0.40;
    fire.color = [[UIColor colorWithRed:0.8 green:0.6 blue:0.4 alpha:0.1] CGColor];
	fire.contents = (id) [[UIImage imageNamed:@"bomb_unit"] CGImage];
    // End // Fire ////////////////////////////////////////////////////////////////
	
    // Begin // Smoke /////////////////////////////////////////////////////////////
    // Create the emitter layers
	self.smokeEmitter = [CAEmitterLayer layer];
    self.smokeEmitter.emitterPosition = bombPoint;
    self.smokeEmitter.emitterShape	= kCAEmitterLayerCircle; // 粒子
	self.smokeEmitter.emitterMode = kCAEmitterLayerAdditive;
    
	// Create the smoke emitter cell
	CAEmitterCell* smoke = [CAEmitterCell emitterCell];
	[smoke setName:@"smoke"];
    
	smoke.birthRate			= 20; //每秒发射的粒子数量
	smoke.emissionLongitude = M_PI*2;
	smoke.velocity			= 100; // 粒子每秒移动的像素数
	smoke.velocityRange		= 30; // 速度变化范围
	smoke.emissionRange		= M_PI*2; // 这是一个cell发射的角度范围(弧度制).M_PI_2(pi/2)是45度(也就是说生成范围会+-45度)
	smoke.yAcceleration		= 0;
    smoke.scaleSpeed		= 1;
    smoke.lifetime			= 1.0; // 一个粒子几秒后消失
    smoke.lifetimeRange		= 0.4;
    smoke.spin				= 0; // 每个粒子的旋转速率
	smoke.spinRange			= 0;
	//smoke.scale				= 0.1;
	smoke.alphaSpeed		= -0.2;
	smoke.scaleSpeed		= 1.0; // 每秒修改粒子大小的百分比  
    smoke.color = [[UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:0.5] CGColor];
    smoke.contents			= (id) [[UIImage imageNamed:@"dazSmoke"] CGImage];
    // End // Smoke /////////////////////////////////////////////////////////////
	
	// Add the smoke emitter cell to the smoke emitter layer
    self.coreEmitter.emitterCells	= [NSArray arrayWithObject:core];
    self.fireEmitter.emitterCells	= [NSArray arrayWithObject:fire];
	self.smokeEmitter.emitterCells	= [NSArray arrayWithObject:smoke];
    
    [self.view.layer addSublayer:self.smokeEmitter];
	[self.view.layer addSublayer:self.fireEmitter];
    [self.view.layer addSublayer:self.coreEmitter];
	
	[self setFireAmount:bomb.m_damage];
    [self startTimerForPropertyAnimation];
}

- (void) setFireAmount:(int)damage
{    
	// Update the fire properties
//	[self.fireEmitter setValue:[NSNumber numberWithInt:(damage*damage*damage*4000)]
//					forKeyPath:@"emitterCells.fire.birthRate"];
//    [self.fireEmitter setValue:[NSNumber numberWithFloat:(damage*400)]
//					forKeyPath:@"emitterCells.fire.velocity"];
//	self.fireEmitter.emitterSize = CGSizeMake(70*damage, 70*damage);
    
    // Update the smoke properties
//    [self.smokeEmitter setValue:[NSNumber numberWithInt:(damage*damage*damage*20)]
//					forKeyPath:@"emitterCells.smoke.birthRate"];
//    [self.smokeEmitter setValue:[NSNumber numberWithFloat:(damage*80)]
//					forKeyPath:@"emitterCells.smoke.velocity"];
//    self.smokeEmitter.emitterSize = CGSizeMake(70*damage, 70*damage);    
    
    CGFloat   birthRate_fire = 0, velocity_fire = 0;
    CGFloat   birthRate_core = 0, velocity_core = 0;
    CGFloat   birthRate_smoke = 0, velocity_smoke = 0;
    CGSize    size_core, size_fire, size_smoke;
    
    switch (damage)
    {
        case 0:
        case 1:
            {
                birthRate_core = 200;
                birthRate_fire = 1000;
                birthRate_smoke = 20;
                velocity_core = 80;
                velocity_fire = 100;                
                velocity_smoke = 80;
                size_core = CGSizeMake(35, 35);
                size_fire = CGSizeMake(70, 70);
                size_smoke = CGSizeMake(70, 70);
            }
            break;
            
        case 2:
            {
                birthRate_core = 800;
                birthRate_fire = 8000;
                birthRate_smoke = 20;
                velocity_core = 200;
                velocity_fire = 300;                
                velocity_smoke = 120;
                size_core = CGSizeMake(70*2, 70*2);
                size_fire = CGSizeMake(70*3, 70*3);
                size_smoke = CGSizeMake(70*3, 70*3);
                
            }
            break;
            
        case 3:
        default:
            {
                birthRate_core = 8000;
                birthRate_fire = 10000;
                birthRate_smoke = 20;
                velocity_core = 200;
                velocity_fire = 300;                
                velocity_smoke = 200;
                size_core = CGSizeMake(70*3, 70*3);
                size_fire = CGSizeMake(70*5, 70*5);
                size_smoke = CGSizeMake(70*5, 70*5);
                
            }
            break;
    }
    
    // Update the core properties
	[self.coreEmitter setValue:[NSNumber numberWithInt:birthRate_fire] forKeyPath:@"emitterCells.core.birthRate"];
    [self.coreEmitter setValue:[NSNumber numberWithFloat:velocity_fire] forKeyPath:@"emitterCells.core.velocity"];
	self.coreEmitter.emitterSize = size_core;
    
    // Update the fire properties
	[self.fireEmitter setValue:[NSNumber numberWithInt:birthRate_fire] forKeyPath:@"emitterCells.fire.birthRate"];
    [self.fireEmitter setValue:[NSNumber numberWithFloat:velocity_fire] forKeyPath:@"emitterCells.fire.velocity"];
	self.fireEmitter.emitterSize = size_fire;

    // Update the smoke properties
    [self.smokeEmitter setValue:[NSNumber numberWithInt:birthRate_smoke] forKeyPath:@"emitterCells.smoke.birthRate"];
    [self.smokeEmitter setValue:[NSNumber numberWithFloat:velocity_smoke] forKeyPath:@"emitterCells.smoke.velocity"];
    self.smokeEmitter.emitterSize = size_smoke;  
}


// 道具释放动画播放时间控制

- (void)startTimerForPropertyAnimation
{
    m_timer_property = [NSTimer scheduledTimerWithTimeInterval:PROPERTY_TIMER_INTERVAL target:self selector:@selector(onTimerForPropertyAnimation) userInfo:nil repeats:FALSE];
}


- (void)onTimerForPropertyAnimation
{
    // Todo...
    // 根据当前道具类型决定结束何种道具释放效果
    switch ([m_propertyViewController getPropertyType]) 
    {
        case LB_PROPERTY_BOMB:
            {
                [coreEmitter setValue:[NSNumber numberWithInt:0] forKeyPath:@"emitterCells.core.birthRate"];
                [fireEmitter setValue:[NSNumber numberWithInt:0] forKeyPath:@"emitterCells.fire.birthRate"];
                [smokeEmitter setValue:[NSNumber numberWithInt:0] forKeyPath:@"emitterCells.smoke.birthRate"];

//                [self.fireEmitter removeFromSuperlayer];
//                self.fireEmitter = nil;
//                [self.smokeEmitter removeFromSuperlayer];
//                self.smokeEmitter = nil;
            }
            break;
            
        case LB_PROPERTY_COLORBALL:
            {
                // Todo...
            }
            break;
            
        default:
            break;
    }
    
    // 结束道具选取状态
    [m_propertyViewController resetPropertyState];
    m_bPropertyPlaying = FALSE;
}

- (void)refreshScoreDisplay
{
    [m_scoreLabel setText:[NSString stringWithFormat:@"%d",gameScore]];
    [m_propertyViewController checkAndChangeBuyButtonsState];
}

@end
